﻿using System;
using System.Web.Mvc;
using BestPracticesMVC.Data.DataModels;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using BestPracticesMVC.Controllers;
using System.Collections.Generic;
using BestPracticesMVC.BL.ViewModels;
using System.Linq;
using BestPracticesMVC.Data.ORM;
using Moq;

namespace UnitTestProject
{
    [TestClass]
    public class UnitTest1
    {
        
        [TestMethod]
        public void TestMethod1()
        {
            List<Author> data = new List<Author>()
            {
                new Author()
                {
                    Id = 7,
                    Name = "Name1",
                    NickName = "Pesho"
                }
            };

            var mockRepos = new Moq.Mock<IUowData>();
            mockRepos.Setup(x => x.Authors.All()).Returns(data.AsQueryable());

            var controller = new HomeController(mockRepos.Object);

            var result = controller.Index() as ViewResult;
            var products = (ICollection<AuthorViewModel>)result.ViewData.Model;
            
            Assert.AreEqual("", result.ViewName);
            Assert.AreEqual(1, products.Count);
        }

        [TestMethod]
        public void TestMethod2()
        {
            List<Author> data = new List<Author>();
           
            var mockRepos = new Moq.Mock<IUowData>();
            mockRepos.Setup(x => x.Authors.Add(It.IsAny<Author>()))
                     .Returns(new Func<Author, Author>(x =>
                     {
                         var newAuthor = new Author()
                         {
                             Id = 7,
                             Name = "Name1",
                             NickName = "Pesho"
                         };
                         data.Add(x);
                         return data.Last();
                     }));

            var controller = new HomeController(mockRepos.Object);
            var result = controller.About() as ViewResult;

            Assert.AreEqual(1, data.Count);
        }
       
        
        [TestMethod]
        public void TestMethod3()
        {
            List<Author> data = new List<Author>();
           
            var mockRepos = new Moq.Mock<IUowData>();
            
            mockRepos.Setup(x => x.Authors.All()).Returns(data.AsQueryable());

            mockRepos.Setup(x => x.Authors.Add(It.IsAny<Author>()))
                     .Returns(new Func<Author, Author>(x =>
                     {
                         data.Add(x);
                         return data.Last();
                     }));

            mockRepos.Setup(x => x.SaveChanges()).Returns(1);


            var controller = new HomeController(mockRepos.Object);
            controller.About();
            controller.About();
            
            var str = controller.ViewData
                                .ModelState
                                .Values
                                .SelectMany(e => e.Errors)
                                .FirstOrDefault()
                                .ErrorMessage;

            Assert.IsTrue(str == "Username is already exist");
        }

        //http://abelperezmartinez.blogspot.com/2014/01/mocking-repository-using-moq.html

        // setup Update method
                //mock.Setup(x => x.Update(It.IsAny<TE>()))
                //    .Callback(new Action<TE>(x =>
                //    {
                //        var i = data.FindIndex(q => q.Id.Equals(x.Id));
                //        data[i] = x;
                //    }));
 
                //// setup FindBy (id)
                //mock.Setup(x => x.FindBy(It.IsAny<TK>()))
                //    .Returns(new Func<TK, TE>(
                //        x => data.Find(q => q.Id.Equals(x))
                //    ));
 
                //// setup Delete
                //mock.Setup(x => x.Delete(It.IsAny<TE>()))
                //    .Callback(new Action<TE>(x => {
                //        var i = data.FindIndex(q => q.Id.Equals(x.Id));
                //        data.RemoveAt(i);
                //        }
                //    ));
      
               // angular  http://www.dotnetcurry.com/showarticle.aspx?ID=1002
    }
}